/*
 * Copyright (c) 2014, KJFrameForAndroid 张涛 (kymjs123@gmail.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package bdhub.littletail.app.utils;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.net.Uri;
import android.os.Build;
import android.os.Vibrator;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.inputmethod.InputMethodManager;

import java.io.File;
import java.security.MessageDigest;
import java.util.List;

import bdhub.littletail.app.LittleTailApplication;
import bdhub.littletail.lib.utils.StringUtil;
import bdhub.littletail.lib.utils.log.CLog;

/**
 * 系统信息工具包
 *
 * Created by FreddyChen on 16/2/23.
 * chenshichao@outlook.com
 */
public final class SystemTool {
	
	/**
	 * 获取设备基本信息<br />
	 * 代码是从友盟统计那里弄过来的
	 *
	 * @return {"device_id": "your_device_id", "mac": "your_device_mac"}
	 */
	public static String getDeviceInfo() {
		Context context = LittleTailApplication.sharedInstance();
	    try{
	      org.json.JSONObject json = new org.json.JSONObject();
	      android.telephony.TelephonyManager tm = (android.telephony.TelephonyManager) context
	          .getSystemService(Context.TELEPHONY_SERVICE);

	      String device_id = tm.getDeviceId();

	      android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) context.getSystemService(Context.WIFI_SERVICE);

	      String mac = wifi.getConnectionInfo().getMacAddress();
	      json.put("mac", mac);

	      if( TextUtils.isEmpty(device_id) ){
	        device_id = mac;
	      }

	      if( TextUtils.isEmpty(device_id) ){
	        device_id = android.provider.Settings.Secure.getString(context.getContentResolver(),android.provider.Settings.Secure.ANDROID_ID);
	      }

	      json.put("device_id", device_id);

	      return json.toString();
	    }catch(Exception e){
	      e.printStackTrace();
	    }
	  return "";
	}

    /**
     * 获取手机IMEI码
     */
    public static String getPhoneIMEI() {
    	String id;
        TelephonyManager tm = (TelephonyManager) LittleTailApplication.sharedInstance().getSystemService(Context.TELEPHONY_SERVICE);
        id = tm.getDeviceId();

        if( TextUtils.isEmpty(id) ){
        	android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) LittleTailApplication.sharedInstance().getSystemService(Context.WIFI_SERVICE);
            String mac = wifi.getConnectionInfo().getMacAddress();
        	id = mac;
	    }

        if (TextUtils.isEmpty(id)) {
        	//如果Android Pad没有IMEI,用此方法获取设备ANDROID_ID：
			id = Secure.getString(LittleTailApplication.sharedInstance().getContentResolver(), Secure.ANDROID_ID);
		}

        return id;
    }

    /**
     * 获取运营商sim卡imsi号
     */
    public static String getPhoneIMSI() {
    	TelephonyManager tm = (TelephonyManager) LittleTailApplication.sharedInstance().getSystemService(Context.TELEPHONY_SERVICE);
    	String imsi = tm.getSubscriberId();
    	if (imsi == null) {
    		imsi = "-1";
		}
    	return imsi;

    	//android.os.SystemProperties在SDK的库中是没有的，需要把Android SDK 目录下data下的layoutlib.jar文件加到当前工程的附加库路径中，就可以Import
    	//return android.os.SystemProperties.get(android.telephony.TelephonyProperties.PROPERTY_IMSI);;
    }

    /**
     * 获取运营商名称
     *
     * @return CMCC、UNICOM、TELECOM
     */
    public static String getSimOperator() {
    	TelephonyManager telManager = (TelephonyManager) LittleTailApplication.sharedInstance().getSystemService(Context.TELEPHONY_SERVICE);
    	String operator = telManager.getSimOperator();
    	if(operator != null){
	    	if(operator.equals("46000") || operator.equals("46002") || operator.equals("46007")){
	    		//中国移动
	    		return "CMCC";
	    	}else if(operator.equals("46001")){
	    		//中国联通
	    		return "UNICOM";
	    	}else if(operator.equals("46003")){
	    		//中国电信
	    		return "TELECOM";
	    	}
    	}
    	return "";
	}

    public static boolean isFroyoOrLater()
    {
        return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.FROYO;
    }

    public static boolean isGingerbreadOrLater()
    {
        return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD;
    }

    public static boolean isHoneycombOrLater()
    {
        return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB;
    }

    public static boolean isHoneycombMR1OrLater() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1;
    }

    public static boolean isICSOrLater()
    {
        return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
    }

    public static boolean isJellyBeanOrLater()
    {
        return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN;
    }

    public static boolean isJellyBeanMR1OrLater()
    {
        return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
    }

    public static boolean isJellyBeanMR2OrLater()
    {
        return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
    }

    public static boolean isKitKatOrLater()
    {
        return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT;
    }

    /**
     * 获取手机系统SDK版本
     *
     * @return 如API 17 则返回 17
     */
    public static int getSDKVersion() {
        return android.os.Build.VERSION.SDK_INT;
    }

    /**
     * 获取系统版本
     *
     * @return 形如2.3.3
     */
    public static String getSystemVersion() {
        return android.os.Build.VERSION.RELEASE;
    }

    /**
     * 获取机型
     *
     * @return
     */
    public static String getDeviceModel() {
		return android.os.Build.MODEL;
	}

    /**
     * 获取系统厂商
     * @return
     * Xiaomi/samsung等
     */
    public static String getMaunfacturer() {
    	return android.os.Build.MANUFACTURER;
    }

    /**
     * 调用系统发送短信
     */
    public static void sendSMS(Context cxt, String smsBody) {
        Uri smsToUri = Uri.parse("smsto:");
        Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri);
        intent.putExtra("sms_body", smsBody);
        cxt.startActivity(intent);
    }

    /**
     * 判断网络是否连接
     */
    public static boolean checkNet(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getActiveNetworkInfo();
        return info != null;// 网络是否连接
    }

    /**
     * 判断是否为wifi联网
     */
    public static boolean isWiFi(Context cxt) {
        ConnectivityManager cm = (ConnectivityManager) cxt
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        // wifi的状态：ConnectivityManager.TYPE_WIFI
        // 3G的状态：ConnectivityManager.TYPE_MOBILE
        State state = cm
                .getNetworkInfo(ConnectivityManager.TYPE_WIFI)
                .getState();
        return State.CONNECTED == state;
    }

    /**
     * 隐藏系统键盘
     *
     * <br>
     * <b>警告</b> 必须是确定键盘显示时才能调用
     */
    public static void hideKeyBoard(Activity aty) {
        ((InputMethodManager) aty
                .getSystemService(Context.INPUT_METHOD_SERVICE))
                .hideSoftInputFromWindow(aty.getCurrentFocus()
                        .getWindowToken(),
                        InputMethodManager.HIDE_NOT_ALWAYS);
    }

    /**
     * 判断当前应用程序是否后台运行
     */
    public static boolean isBackground(Context context) {
        ActivityManager activityManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningAppProcessInfo> appProcesses = activityManager
                .getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
            if (appProcess.processName.equals(context
                    .getPackageName())) {
                if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
                    // 后台运行
                    return true;
                } else {
                    // 前台运行
                    return false;
                }
            }
        }
        return false;
    }

    /**
     * 判断手机是否处理睡眠
     */
    public static boolean isSleeping(Context context) {
        KeyguardManager kgMgr = (KeyguardManager) context
                .getSystemService(Context.KEYGUARD_SERVICE);
        boolean isSleeping = kgMgr.inKeyguardRestrictedInputMode();
        return isSleeping;
    }

    /**
     * 安装apk
     *
     * @param context
     * @param file
     */
    public static void installApk(Context context, File file) {
        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.setType("application/vnd.android.package-archive");
        intent.setData(Uri.fromFile(file));
        intent.setDataAndType(Uri.fromFile(file),
                "application/vnd.android.package-archive");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    /**
     * 获取当前应用的版本号
     *
     * @return version code
     */
    public static int getAPPVersionCode(Context context) {
    	int verstionCode = 0;
    	try {
    		verstionCode = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
		} catch (NameNotFoundException e) {
            e.printStackTrace();
		}
    	return verstionCode;
    }

    private static String versionName;
    /**
     * 获取当前应用的版本名
     *
     * @return version name
     */
    public static String getAPPVersionName() {
    	if (TextUtils.isEmpty(versionName)) {
    		try {
	    		versionName = LittleTailApplication.sharedInstance().getPackageManager()
	    				.getPackageInfo(LittleTailApplication.sharedInstance().getPackageName(), 0).versionName;
    		} catch (NameNotFoundException e) {
    			versionName = "";
                e.printStackTrace();
    		}
		}
    	return versionName;
//    	String name = "";
//    	try {
//    		name = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
//		} catch (NameNotFoundException e) {
//			CLog.handleException(e);
//		}
//    	return name;
    }

	/**
	 * 根据版本名来判断是否有新版本
	 *
	 * @param context
	 * @param newVersion
	 * @return
	 */
	public static boolean isNewVersion(Context context, String newVersion) {
		if (StringUtil.isEmpty(newVersion)) {
			return false;
		}
		String currentVersion = getAPPVersionName();
		if (currentVersion.equals(newVersion)) {
			return false;
		}
		try {
			String[] version1Array = currentVersion.split("\\.");
			String[] version2Array = newVersion.split("\\.");
			int minLen = Math.min(version1Array.length, version2Array.length);
			for (int i = 0; i < minLen; i++) {
				if (Integer.parseInt(version1Array[i]) != Integer.parseInt(version2Array[i])) {
					return Integer.parseInt(version2Array[i]) > Integer.parseInt(version1Array[i]);
				}
			}
		} catch (Exception e) {
			// compare failed
		}
		return true;
	}

    /**
     * 回到home，后台运行
     */
    public static void goHome(Context context) {
        Intent mHomeIntent = new Intent(Intent.ACTION_MAIN);
        mHomeIntent.addCategory(Intent.CATEGORY_HOME);
        mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        context.startActivity(mHomeIntent);
    }

    /**
     * 获取应用签名
     *
     * @param context
     * @param pkgName
     */
    public static String getSign(Context context, String pkgName) {
        try {
            PackageInfo pis = context.getPackageManager()
                    .getPackageInfo(pkgName,
                            PackageManager.GET_SIGNATURES);
            return hexdigest(pis.signatures[0].toByteArray());
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取应用渠道信息
     * @param context
     * @param key 键，根据key获取对应的value
     * @return
     */
    public static String getAppMetaData(Context context, String key) {
    	if(null == context || TextUtils.isEmpty(key))
    		return null;

    	String resultData = null;
    	try {
	    	PackageManager packageManager = context.getPackageManager();
	    	if(null != packageManager) {
				ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
				if(null != applicationInfo && null != applicationInfo.metaData) {
					resultData = applicationInfo.metaData.getString(key);
				}
	    	}
    	} catch (NameNotFoundException e) {
			e.printStackTrace();
		}

    	return resultData;
    }

    /**
     * 将签名字符串转换成需要的32位签名
     */
    private static String hexdigest(byte[] paramArrayOfByte) {
        final char[] hexDigits = { 48, 49, 50, 51, 52, 53, 54, 55,
                                  56, 57, 97, 98, 99, 100, 101, 102 };
        try {
            MessageDigest localMessageDigest = MessageDigest
                    .getInstance("MD5");
            localMessageDigest.update(paramArrayOfByte);
            byte[] arrayOfByte = localMessageDigest.digest();
            char[] arrayOfChar = new char[32];
            for (int i = 0, j = 0;; i++, j++) {
                if (i >= 16) {
                    return new String(arrayOfChar);
                }
                int k = arrayOfByte[i];
                arrayOfChar[j] = hexDigits[(0xF & k >>> 4)];
                arrayOfChar[++j] = hexDigits[(k & 0xF)];
            }
        } catch (Exception e) {
        }
        return "";
    }

    /**
     * 获取设备的可用内存大小
     *
     * @param cxt
     *            应用上下文对象context
     * @return 当前内存大小
     */
    public static int getDeviceUsableMemory(Context cxt) {
        ActivityManager am = (ActivityManager) cxt
                .getSystemService(Context.ACTIVITY_SERVICE);
        MemoryInfo mi = new MemoryInfo();
        am.getMemoryInfo(mi);
        // 返回当前系统的可用内存
        return (int) (mi.availMem / (1024 * 1024));
    }

    /**
     * 清理后台进程与服务
     *
     * @param cxt
     *            应用上下文对象context
     * @return 被清理的数量
     */
    @TargetApi(Build.VERSION_CODES.FROYO)
    public static int gc(Context cxt) {
        long i = getDeviceUsableMemory(cxt);
        int count = 0; // 清理掉的进程数
        ActivityManager am = (ActivityManager) cxt
                .getSystemService(Context.ACTIVITY_SERVICE);
        // 获取正在运行的service列表
        List<RunningServiceInfo> serviceList = am
                .getRunningServices(100);
        if (serviceList != null)
            for (RunningServiceInfo service : serviceList) {
                if (service.pid == android.os.Process.myPid())
                    continue;
                try {
                    android.os.Process.killProcess(service.pid);
                    count++;
                } catch (Exception e) {
                    e.getStackTrace();
                    continue;
                }
            }

        if (getSDKVersion() >= Build.VERSION_CODES.FROYO) {
            // 获取正在运行的进程列表
            List<RunningAppProcessInfo> processList = am
                    .getRunningAppProcesses();
            if (processList != null) {
            	for (RunningAppProcessInfo process : processList) {
                    // 一般数值大于RunningAppProcessInfo.IMPORTANCE_SERVICE的进程都长时间没用或者空进程了
                    // 一般数值大于RunningAppProcessInfo.IMPORTANCE_VISIBLE的进程都是非可见进程，也就是在后台运行着
                    if (process.importance > RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
                        // pkgList 得到该进程下运行的包名
                        String[] pkgList = process.pkgList;
                        for (String pkgName : pkgList) {
                            CLog.d("GC", "======正在杀死包名：" + pkgName);
                            try {
                                am.killBackgroundProcesses(pkgName);
                                count++;
                            } catch (Exception e) { // 防止意外发生
                                e.getStackTrace();
                                continue;
                            }
                        }
                    }
                }
            }
		}

        CLog.d("GC", "清理了" + (getDeviceUsableMemory(cxt) - i)
                + "M内存");
        return count;
    }

    public static void vibrate(Context context) {
    	Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    	vibrator.vibrate(30);
	}

    @SuppressLint("NewApi")
    public static void copy2clipboard(Context context, String text) {
    	if(getSDKVersion() < android.os.Build.VERSION_CODES.HONEYCOMB) {
    	    android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
    	    clipboard.setText(text);
    	} else {
    	    android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
    	    android.content.ClipData clip = android.content.ClipData.newPlainText("text label", text);
    	    clipboard.setPrimaryClip(clip);
    	}
	}
}